package com.toymate.common.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.toymate.ai.tts.TTSFactory;
import com.toymate.modules.iot.entity.IotMessageLog;
import com.toymate.modules.iot.entity.IotRole;
import com.toymate.modules.iot.service.IotMessageLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.iot.mqtt.spring.server.MqttServerTemplate;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * PushUtils
 *
 * @author weirdor (179946422@qq.com)
 * @version v1.0.0
 */
@Slf4j
@Component
@AllArgsConstructor
public class PushUtils {

    private static final String TOPIC_PATTERN = "/%s/%s/function/get";
    private final MqttServerTemplate mqttServerTemplate;
    private final FileStorageService fileStorageService;
    private final IotMessageLogService iotMessageLogService;

    public void pushMessage(String productId, String deviceNum, String answer, int index, IotRole role) {
        try {
            Optional<String> audioFile = Objects.requireNonNull(TTSFactory.build(role)).speechSynthesizer(deviceNum, answer);
            if (audioFile.isPresent()) {
                String url = "";
                //判断optionalString 是否是http或者https
                if (audioFile.get().startsWith("http") || audioFile.get().startsWith("https")) {
                    url = audioFile.get();
                } else {
                    File file1 = new File(audioFile.get());
                    String[] originalFilename = file1.getName().split("\\.");
                    String dateStr = DateUtil.today();
                    String path = dateStr + "/";
                    String fileName = originalFilename[0] + "-" + IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file1.getName());
                    String objectName = path + fileName;
                    FileInfo upload = fileStorageService.of(file1, objectName, "audio/mp3").upload();
                    url = upload.getUrl();
                    FileUtil.del(audioFile.get());
                }
                log.info("语音合成成功：{}", url);
                if (index == 0) {
                    //todo 开始推送
                    play(productId, deviceNum, url, "", index);
                }
                String finalUrl = url;
                iotMessageLogService.remove(Wrappers.<IotMessageLog>lambdaQuery().eq(IotMessageLog::getDeviceId, deviceNum).eq(IotMessageLog::getProductId, productId).ge(IotMessageLog::getSortNum, index));
                IotMessageLog messageLog = new IotMessageLog();
                messageLog.setProductId(productId);
                messageLog.setDeviceId(deviceNum);
                messageLog.setMessageUrl(finalUrl);
                messageLog.setSortNum(index);
                messageLog.setMessageContent(answer);
                messageLog.insert();
            }
        } catch (Exception e) {
            log.error("Coze推送消息异常：{}", e.getMessage());
        }

    }

    /**
     * 播放音频推送
     *
     * @return
     */
    public void play(String productId, String deviceNum, String video, String messageId, int index) {
        if (StrUtil.isEmpty(productId)) {
            Assert.notBlank(productId, "产品ID不能为空");
        }
        if (StrUtil.isEmpty(deviceNum)) {
            Assert.notBlank(deviceNum, "设备编号不能为空");
        }
        // 创建请求数据的Map
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("type", 2);
        map.put("video", video);
        map.put("index", index);
        try {
            // 使用格式化字符串替代字符串拼接，提高代码可读性
            String topic = String.format(TOPIC_PATTERN, productId, deviceNum);
            byte[] message = JSON.toJSONString(map).getBytes();

            // 发布消息，若出现异常则捕获处理
            mqttServerTemplate.publishAll(topic, message);
            log.info("消息发布成功，主题: {}, 消息: {}", topic, new String(message));
        } catch (Exception e) {
            log.error("消息发布失败", e);
        }
    }
}
